package com.brillilab.service.logic.lab;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import com.brillilab.common.constant.ResultEnum;
import com.brillilab.common.entity.PageVo;
import com.brillilab.common.exceptions.BrillilabException;
import com.brillilab.dao.mapper.lab.LabMapper;
import com.brillilab.domain.enums.common.BoolEnum;
import com.brillilab.domain.enums.lab.LabEnum;
import com.brillilab.domain.enums.lab.LabMemberEnum;
import com.brillilab.domain.enums.lab.LabMemberPowerEnum;
import com.brillilab.domain.enums.lab.UserEnum;
import com.brillilab.domain.enums.method.MethodDealStateEnum;
import com.brillilab.domain.enums.method.RecommendAuditStateEnum;
import com.brillilab.domain.enums.team.TeamMemberStateEnum;
import com.brillilab.domain.pa.lab.PowerModifyPa;
import com.brillilab.domain.po.lab.Lab;
import com.brillilab.domain.po.lab.LabMember;
import com.brillilab.domain.po.lab.LabMemberPower;
import com.brillilab.domain.po.method.MethodRecommend;
import com.brillilab.domain.po.method.MethodRecommendAudit;
import com.brillilab.domain.po.method.MethodRecommendReceive;
import com.brillilab.domain.po.team.Team;
import com.brillilab.domain.po.team.TeamMember;
import com.brillilab.domain.po.user.Users;
import com.brillilab.domain.vo.home.HomeMyAuditVo;
import com.brillilab.domain.vo.lab.LabInfoVo;
import com.brillilab.domain.vo.lab.LabMemberAdd;
import com.brillilab.domain.vo.lab.LabMemberPageGet;
import com.brillilab.domain.vo.lab.LabMemberVo;
import com.brillilab.domain.vo.lab.PowerAndDutyModifyVo;
import com.brillilab.domain.vo.method.MethodRecommendDeal;
import com.brillilab.domain.vo.user.UserBindLab;
import com.brillilab.domain.vo.user.UserInfoVo;
import com.brillilab.service.core.lab.ILabMemberPowerService;
import com.brillilab.service.core.lab.ILabMemberService;
import com.brillilab.service.core.lab.ILabService;
import com.brillilab.service.core.lab.ILabUserCardService;
import com.brillilab.service.core.method.IMethodRecommendAuditService;
import com.brillilab.service.core.method.IMethodRecommendReceiveService;
import com.brillilab.service.core.method.IMethodRecommendService;
import com.brillilab.service.core.team.ITeamMemberService;
import com.brillilab.service.core.team.ITeamService;
import com.brillilab.service.core.user.IUsersService;
import com.brillilab.service.logic.message.MessageLogic;
import com.brillilab.service.logic.method.MethodRecommendLogic;
import com.brillilab.service.logic.team.TeamLogic;
import com.brillilab.service.logic.user.UsersLogic;
import com.brillilab.service.module.message.producer.MessageProducer;
import com.brillilab.service.module.message.template.enums.MessageTypeEnum;
import com.brillilab.service.module.message.template.impl.usercenter.AuthByModifySuccessTemplate;
import com.brillilab.service.module.message.template.impl.usercenter.EntryLabMsgTemplate;
import com.brillilab.service.module.message.template.impl.usercenter.ReCallLabTemplate;
import com.brillilab.service.module.message.template.impl.usercenter.RemoveLabMsgTemplate;

import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.PinyinHelper;

@Service
@Slf4j
@Transactional
public class LabMemberLogic {

	@Resource
	private ILabMemberService labMemberService;
	@Resource
	private ILabMemberPowerService labMemberPowerService;
	@Resource
	private LabMapper labMapper;
	@Resource
	private ILabService labService;
	@Resource
	private IUsersService usersService;
	@Resource
	private UsersLogic usersLogic;
	@Resource
	private MethodRecommendLogic methodRecommendLogic;
	@Resource
	private IMethodRecommendService methodRecommendService;
	@Resource
	private IMethodRecommendAuditService methodRecommendAuditService;
	@Resource
	private IMethodRecommendReceiveService methodRecommendReceiveService;
	@Resource
	private MessageLogic messageLogic;
	@Resource
	private ILabUserCardService labUserCardService;
	@Resource
	private TeamLogic teamLogic;
	@Resource
	private ITeamMemberService teamMemberService;
	@Resource
	private ITeamService teamService;
	@Resource
	private MessageProducer messageProducer;

	/**
	 * 新增成员
	 *
	 * @param req
	 * @param userInfo
	 * @return
	 * @date 2019-03-28
	 */
	public LabMember addLabMember(LabMemberAdd req, UserInfoVo userInfo) {
		Users user = usersLogic.getUser(req.getUserId());
		Assert.notNull(user, "用户不存在！");

		// 获取实验室信息
		Lab lab = this.getLabAndAssertExist(userInfo.getLabId());

		LabMember labMemberExist = labMemberService.selectMemberAllState(userInfo.getLabId(), req.getUserId());
		Assert.isTrue(
				labMemberExist == null || labMemberExist.getState().equals(LabMemberEnum.State.STATE_OUT.getValue()),
				"该用户已加入当前实验室！");

		boolean b = messageLogic.checkVerifyCode(user.getMobile(), req.getSmsCode());
		Assert.isTrue(b, "验证码错误！");

		if (labMemberExist != null) {
			labMemberExist.setDuty(req.getDuty());
			labMemberExist.setEntryDate(req.getEntryDate() != null ? req.getEntryDate() : new Date());
			labMemberExist.setState(LabMemberEnum.State.STATE_IN.getValue());
			labMemberService.updateById(labMemberExist);
		} else {
			labMemberExist = new LabMember();
			labMemberExist.setLabId(userInfo.getLabId());
			labMemberExist.setUserId(req.getUserId());
			labMemberExist.setDuty(req.getDuty());
			labMemberExist.setEntryDate(req.getEntryDate() != null ? req.getEntryDate() : new Date());
			labMemberService.add(labMemberExist);
		}

		// 接收推荐方法
		this.recommendMethodInit(lab, labMemberExist);

		// 推送
		Long labId = labMemberExist.getLabId();// 实验室ID
		Long receiverId;// 接收人：实验室PI

		Lab labInfo = labMapper.selectById(labId);
		receiverId = labInfo != null ? labInfo.getOwnerId() : 0;

		// 接收者实验成员Id
		LabMember receiverInfo = labMemberService.selectMember(labId, receiverId);
		Long labMemberId = receiverInfo != null ? receiverInfo.getId() : 0;
		// 被添加人信息
		UserInfoVo labMemberInfo = usersLogic.getUserById(req.getUserId());
		EntryLabMsgTemplate entryLabMsgTemplate = new EntryLabMsgTemplate(labId, receiverId, labMemberId,
				labMemberInfo.getName(), // 被添加用户姓名
				userInfo.getLabName(), userInfo.getName(), labMemberInfo.getId());
		messageProducer.sendMessagePush(entryLabMsgTemplate);
		return labMemberExist;
	}

	/**
	 * 权限开通成员列表
	 *
	 * @param power
	 * @param userInfoVo
	 * @return
	 */
	public Map<String, List<LabMemberVo>> getPowerMemberListMap(String power, UserInfoVo userInfoVo) {

		List<LabMemberVo> isOpenRs = this.selectLabMemberVoList(userInfoVo.getLabId(), power, 1);
		List<LabMemberVo> notOpenRs = this.selectLabMemberVoList(userInfoVo.getLabId(), power, 0);

		LabMember owner = labMemberService.selectMemberAllState(userInfoVo.getLabId(), userInfoVo.getOwnerId());
		if (owner != null) {
			isOpenRs = this.selectLabMemberVoList(userInfoVo.getLabId(), power, 1).stream()
					.filter(e -> !e.getLabMemberId().equals(owner.getId())).collect(Collectors.toList());
			notOpenRs = this.selectLabMemberVoList(userInfoVo.getLabId(), power, 0).stream()
					.filter(e -> !e.getLabMemberId().equals(owner.getId())).collect(Collectors.toList());
		}

		Map<String, List<LabMemberVo>> resultMap = new HashMap<>();
		resultMap.put("isOpen", isOpenRs);
		resultMap.put("notOpen", notOpenRs);
		return resultMap;
	}

	/**
	 * 权限的实验室成员列表
	 *
	 * @param labId
	 * @param power
	 * @param isOpen
	 * @return
	 */
	public List<LabMemberVo> selectLabMemberVoList(Long labId, String power, Integer isOpen) {

		Assert.isTrue(LabMemberPowerEnum.Power.getKey(power) != null, "参数错误");
		List<LabMemberVo> labMemberVoList = labMemberService.selectList(labId, LabMemberEnum.State.STATE_IN.getValue());
		List<LabMemberVo> list = null;
		list = labMemberVoList.stream().filter(e -> {
			List<LabMemberPower> labMemberPowers = e.getPowerList();
			boolean openFlag = false;
			if (!CollectionUtils.isEmpty(labMemberPowers)) {
				for (LabMemberPower labMemberPower : labMemberPowers) {
					if (labMemberPower.getPower().equals(power)) {
						openFlag = true;
						break;
					}
				}
			}
			return isOpen == 1 ? openFlag : (!openFlag);
		}).collect(Collectors.toList());

		return list;
	}

	/**
	 * 某状态实验室所有成员
	 *
	 * @param labId
	 * @param state
	 * @return
	 */
	public List<LabMemberVo> selectList(Long labId, Integer state) {
		PageVo<LabMemberVo> labMemberVoPageVo = labMemberService.selectPage(labId, state, 1, 100000);
		List<LabMemberVo> labMemberVoList = labMemberVoPageVo.getContent();
		return setLabOwner(labId, labMemberVoList);
	}

	private List<LabMemberVo> setLabOwner(Long labId, List<LabMemberVo> list) {
		Lab lab = labMapper.selectById(labId);
		return list.stream().map(labMemberVo -> {
			if (labMemberVo.getUserId().equals(lab.getOwnerId())) {
				labMemberVo.setIsOwner(true);
			} else {
				labMemberVo.setIsOwner(false);
			}
			return labMemberVo;
		}).collect(Collectors.toList());
	}

	/**
	 * 实验室成员移出/返回
	 *
	 * @return
	 * @Params labMemberId
	 * @Params state 成员状态必填I:1-正常，2-移出
	 * @Params operator 操作人姓名
	 */
	@Transactional
	public boolean outOrReturnLab(Long labMemberId, Integer state, String operator) {
		LabMember labMember = labMemberService.selectById(labMemberId);
		Assert.notNull(labMember, "用户不是该实验室历史成员！");

		Lab lab = labService.selectById(labMember.getLabId());
		Assert.isTrue(lab != null && lab.getState().equals(LabEnum.State.NORMAL.getValue()), "实验室不存在或已被删除！");

		Long labId = labMember.getLabId();// 实验室ID
		Long receiverId;// 接收人Id
		receiverId = labMember.getUserId();// 接收人为被操作用户

		/* 接收者实验成员Id */
		LabMember receiverInfo = labMemberService.selectMember(labId, receiverId);
		Long receiverLabMemberId = receiverInfo != null ? receiverInfo.getId() : 0;

		if (state == 2) {
			Assert.isTrue(labMember.getState().equals(LabMemberEnum.State.STATE_IN.getValue()), "成员不存在或已移出实验室！");
			Assert.isTrue(!lab.getOwnerId().equals(labMember.getUserId()), "实验室所有者无法被移出实验室！");
			// (1)被移出实验室设置下一实验室为默认，无实验室至null
			List<LabInfoVo> labList = usersLogic.getLabList(labMember.getUserId());
			if (labList != null && labList.size() > 1) {
				for (LabInfoVo e : labList) {
					if (!e.getLabId().equals(lab.getId())) {
						Users users = usersService.selectUser(labMember.getUserId(), UserEnum.State.NORMAL.getValue());
						users.setLabId(e.getLabId());
						usersService.updateById(users);
						usersLogic.setRefreshUser(labMemberId, "您已被移出" + lab.getName() + "，自动为您切换到" + e.getName(),
								true);
						break;
					}
				}
			} else {
				usersService.setLabIdNull(labMember.getUserId());
				usersLogic.setRefreshUser(labMemberId, "您已被移出" + lab.getName() + "，当前未加入其他实验室", true);
			}
			// (2)研究小组成员移除 若是组长，解散小组
			TeamMember teamMember = teamMemberService.selectOneByLabIdAndLabMemberId(labId, labMemberId);
			if (teamMember != null) {
				if (teamMember.getIsLeader().equals(BoolEnum.TRUE.getValue())) {
					Team team = teamService.selectOneByLeaderId(teamMember.getLabMemberId());
					team.setIsDelete(BoolEnum.TRUE.getValue());

					List<TeamMember> teamMembers = teamMemberService.selectListByTeamId(team.getId());
					teamMembers.forEach(e -> e.setState(TeamMemberStateEnum.OUT.getState()));

					teamService.updateById(team);
					teamMemberService.updateBatch(teamMembers, team.getId());
				} else {
					teamMember.setState(TeamMemberStateEnum.OUT.getState());
					teamMemberService.updateById(teamMember);
				}

			}

			// (3)消息推送（移除）
			RemoveLabMsgTemplate removeLabMsgTemplate = new RemoveLabMsgTemplate(labId, receiverId, receiverLabMemberId,
					lab.getName(), operator);
			messageProducer.sendMessagePush(removeLabMsgTemplate);

		} else if (state == 1) {
			// 用户被召回实验室，如果没有实验室则设置默认实验室
			Users users = usersService.selectUser(labMember.getUserId(), UserEnum.State.NORMAL.getValue());
			Assert.notNull(users, "用户状态异常！");

			LabMember exist = labMemberService.selectByLabIdAndUserId(labId, users.getId());
			if (exist != null) {
				throw new BrillilabException(ResultEnum.FAILURE, "用户已存在该实验室！");
			}

			if (users.getLabId() == null) {
				users.setLabId(labMember.getLabId());
				usersService.updateById(users);
			}
			// 消息推送（召回）
			ReCallLabTemplate reCallLabTemplate = new ReCallLabTemplate(labId, receiverId, receiverLabMemberId,
					lab.getName(), operator);
			messageProducer.sendMessagePush(reCallLabTemplate);
		}

		return labMemberService.updateState(labMemberId, state);
	}

	/**
	 * 注册用户直接成为实验室成员
	 *
	 * @param req
	 * @return
	 */
	public LabMember joinLabBecomeMember(UserBindLab req) {
		// 获取用户信息
		Users user = this.getUsersAndAssertExist(req.getMobile(), req.getPassword());
		// 获取实验室信息
		Lab lab = this.getLabAndAssertExist(req.getLabId());
		// 判断用户是否存在
		LabMember labMemberExist = labMemberService.selectMemberAllState(req.getLabId(), user.getId());
		Assert.isTrue(
				labMemberExist == null || labMemberExist.getState().equals(LabMemberEnum.State.STATE_OUT.getValue()),
				"该用户已加入当前实验室！");

		// 更新用户实验室
		if (user.getLabId() == null) {
			user.setLabId(lab.getId());
			user.setUpdateTime(new Date());
			usersService.updateById(user);
		}

		// 添加成员
		if (labMemberExist != null) {
			labMemberExist.setDuty(req.getDuty());
			labMemberExist.setEntryDate(req.getEntryDate() != null ? req.getEntryDate() : new Date());
			labMemberExist.setState(LabMemberEnum.State.STATE_IN.getValue());
			labMemberService.updateById(labMemberExist);
		} else {
			labMemberExist = this.createLabMemberAndInsert(req.getLabId(), user.getId(), req.getDuty(),
					req.getEntryDate());
		}

		// 绑卡
		if (StringUtils.isNotBlank(req.getCardNo())) {
			labUserCardService.bindCard(req.getLabId(), req.getCardNo(), user.getId());
		}

		// 接收推荐方法
		this.recommendMethodInit(lab, labMemberExist);

		// TODO 推送
		return labMemberExist;
	}

	public void recommendMethodInit(Lab lab, LabMember labMember) {
		List<MethodRecommendAudit> audits = methodRecommendAuditService.selectByLabIdAndState(lab.getId(),
				RecommendAuditStateEnum.Recommend.getState());
		List<MethodRecommend> methodRecommends = methodRecommendService.selectListByLabId(lab.getId());
		// 已接收的不再接收，筛选需要接收的
		List<MethodRecommendReceive> receiveList = methodRecommendReceiveService
				.selectByLabIdAnLabMemberIdAndState(labMember.getLabId(), labMember.getId(), 1);
		List<Long> existRecommendIds = receiveList.stream().map(MethodRecommendReceive::getMethodRecommendId)
				.collect(Collectors.toList());
		List<MethodRecommend> methodShouldRecommends = methodRecommends.stream()
				.filter(e -> !existRecommendIds.contains(e.getId())).collect(Collectors.toList());
		// 进行接收
		if (audits != null && audits.size() > 0 && methodShouldRecommends != null
				&& methodShouldRecommends.size() > 0) {
			List<MethodRecommendDeal> deals = new ArrayList<>();
			UserInfoVo userInfo = null;
			for (MethodRecommendAudit audit : audits) {
				MethodRecommend methodRecommend = methodShouldRecommends.stream()
						.filter(e -> e.getMethodId().equals(audit.getRecommendMethodId())).findFirst().orElse(null);
				if (methodRecommend != null) {
					MethodRecommendDeal deal = new MethodRecommendDeal();
					deal.setRecommendId(methodRecommend.getId());
					deal.setState(MethodDealStateEnum.Accept.getState());

					userInfo = new UserInfoVo();
					userInfo.setId(labMember.getUserId());
					userInfo.setLabMemberId(labMember.getId());
					userInfo.setLabId(lab.getId());
					userInfo.setLabName(lab.getName());
					deals.add(deal);
				}
			}

			log.info("新成员应接收推荐的推荐方法条数： {}  条", deals.size());

			if (!CollectionUtils.isEmpty(deals)) {
				final UserInfoVo userInfo1 = userInfo;
				methodRecommendLogic.recommendDealBatch(deals, userInfo1);
			}
		}

	}

	private Lab getLabAndAssertExist(Long labId) {
		Lab lab = labService.selectById(labId);
		Assert.notNull(lab, "实验室不存在！");
		return lab;
	}

	private Users getUsersAndAssertExist(String mobile, String password) {
		Users users = usersService.selectUser(mobile, UserEnum.State.NORMAL.getValue());
		Assert.notNull(users, "手机号未注册！");
		Assert.isTrue(users.getPassword().equals(DigestUtils.md5Hex(password).toUpperCase()), "密码错误！");
		return users;
	}

	public LabMember createLabMemberAndInsert(Long labId, Long userId, String duty, Date entryDate) {
		LabMember labMember = new LabMember();
		labMember.setLabId(labId);
		labMember.setUserId(userId);
		labMember.setDuty(duty);
		labMember.setEntryDate(entryDate != null ? entryDate : new Date());
		labMemberService.add(labMember);
		return labMember;
	}

	/**
	 * 实验室成员列表排序
	 *
	 * @param req
	 * @param page
	 * @param pageNum
	 * @param pageSize
	 */
	public void lastStepSortResult(LabMemberPageGet req, PageVo<LabMemberVo> page, Integer pageNum, Integer pageSize) {
		pageNum = pageNum > 0 ? pageNum : 1;
		pageSize = pageSize > 0 ? pageSize : 10;

		List<LabMemberVo> content = page.getContent();
		if (req.getState().equals(LabMemberEnum.State.STATE_IN.getValue())) {
			LabMemberVo owner = content.stream().filter(LabMemberVo::getIsOwner).findFirst().orElse(null);
			content = content.stream().filter(e -> !e.getIsOwner()).collect(Collectors.toCollection(LinkedList::new));
			// 中 英 分开
			List<LabMemberVo> en = getLabMemberEn(content);
			List<LabMemberVo> cn = getLabMemberCn(content);
			// 排序
			en = sortList(req.getState(), en);
			cn = sortList(req.getState(), cn);
			// 合并
			content = en;
			content.addAll(cn);
			// owner第一
			((LinkedList) content).addFirst(owner);
		} else {
			content = sortList(req.getState(), content);
		}
		// 最后结果
		getLastPageResult(page, pageNum, pageSize, content);
	}

	private void getLastPageResult(PageVo<LabMemberVo> page, Integer pageNum, Integer pageSize,
			List<LabMemberVo> content) {
		int startRow = pageSize * (pageNum - 1);
		int totalRow = content.size();
		int totalPage = totalRow % pageSize > 0 ? totalRow / pageSize + 1 : totalRow / pageSize;
		page.setContent(content.subList(startRow, (startRow + pageSize > totalRow) ? totalRow : startRow + pageSize));
		page.setHasPrevious(pageNum > 1);
		page.setHasNext(pageNum < totalPage);
		page.setPageNum(pageNum);
		page.setPageSize(pageSize);
		page.setTotalRow(totalRow);
		page.setTotalPage(totalPage);
		page.setStartRow(startRow + 1);
	}

	private List<LabMemberVo> getLabMemberCn(List<LabMemberVo> content) {
		return content.stream().filter(e -> {
			try {
				byte[] bytes1 = e.getUserName().substring(0, 1).getBytes("utf-8");
				return bytes1.length == 3;
			} catch (UnsupportedEncodingException ex) {
				ex.printStackTrace();
				return false;
			}
		}).collect(Collectors.toList());
	}

	private List<LabMemberVo> getLabMemberEn(List<LabMemberVo> content) {
		return content.stream().filter(e -> {
			try {
				byte[] bytes1 = e.getUserName().substring(0, 1).getBytes("utf-8");
				return bytes1.length < 3;
			} catch (UnsupportedEncodingException ex) {
				ex.printStackTrace();
				return false;
			}
		}).collect(Collectors.toList());
	}

	private List<LabMemberVo> sortList(Integer state, List<LabMemberVo> content) {
		if (state.equals(LabMemberEnum.State.STATE_IN.getValue())) {
			// 根据姓名首字母拼音正序
			content = content.stream().filter(e -> !e.getIsOwner()).sorted((e1, e2) -> {
				try {
					char p1 = getNameFirstChar(e1.getUserName());
					char p2 = getNameFirstChar(e2.getUserName());
					return Integer.compare((int) p1, (int) p2);
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
					return 0;
				}
			}).collect(Collectors.toCollection(LinkedList::new));
		} else if (state.equals(LabMemberEnum.State.STATE_OUT.getValue())) {
			// 排序 根据用户退出时间倒序
			content = content.stream()
					.sorted((e1, e2) -> Long.compare(e2.getOutDate().getTime(), e1.getOutDate().getTime()))
					.collect(Collectors.toList());
		}
		return content;
	}

	public char getNameFirstChar(String name) throws UnsupportedEncodingException {
		name = name.toLowerCase();
		byte[] bytes1 = name.substring(0, 1).getBytes("utf-8");
		char p1 = ' ';
		if (bytes1.length == 3) {
			p1 = PinyinHelper.toHanyuPinyinStringArray(name.charAt(0))[0].charAt(0);
		} else {
			p1 = name.charAt(0);
		}
		return p1;
	}

	/**
	 * 修改实验室成员权限
	 *
	 * @param labMemberId
	 * @param powers
	 * @param userInfo
	 * @return
	 */
	public boolean doModifyPower(Long labMemberId, String[] powers, UserInfoVo userInfo) {
		// 1、不能对管理员
		Assert.isTrue(!labMemberService.isOwner(userInfo.getLabId(), labMemberId), "您不能对管理员进行此项操作！");

		boolean contains = ArrayUtils.contains(powers, LabMemberPowerEnum.Power.USER_MANAGE.getValue());
		boolean isPower = labMemberPowerService.isPower(userInfo.getLabId(), labMemberId,
				LabMemberPowerEnum.Power.USER_MANAGE);
		// 2、labMemberId有管理员权限，userInfo不是管理员，不能取消用户管理员权限
		Assert.isTrue(!(isPower && !userInfo.getId().equals(userInfo.getOwnerId()) && !contains), "您不能取消用户管理权限！");

		// 3、userInfo不是管理员，并且不是操作自己，不能操作管理员权限
		Assert.isTrue(!(!userInfo.getId().equals(userInfo.getOwnerId())
				&& !userInfo.getLabMemberId().equals(labMemberId) && !isPower && contains), "您不能操作用户管理权限！");

		boolean b = labMemberPowerService.modifyPower(userInfo.getLabId(), labMemberId, powers);

		usersLogic.setRefreshUser(labMemberId, "您的权限已被修改，请刷新用户信息！", false);

		if (b) {
			powerModifyMessagePush(labMemberId, userInfo);
		}
		return b;
	}

	private void powerModifyMessagePush(Long labMemberId, UserInfoVo userInfo) {
		// 推送提醒(修改成功)
		Long receiverId;// 接收人：被修改用户
		LabMember labMember = labMemberService.selectById(labMemberId);
		receiverId = labMember != null ? labMember.getUserId() : 0;

		// 过滤操作人本人的消息通知
		if (!receiverId.equals(userInfo.getId())) {
			AuthByModifySuccessTemplate authByModifySuccessTemplate = new AuthByModifySuccessTemplate(
					userInfo.getLabId(), receiverId, labMemberId, userInfo.getName(), receiverId);
			messageProducer.sendMessagePush(authByModifySuccessTemplate);
		}
	}

	/**
	 * 权限开关
	 *
	 * @param labMemberId
	 * @param power
	 * @param isOpen
	 * @param userInfo
	 */
	public void doModifyPowerOne(Long labMemberId, String power, Integer isOpen, UserInfoVo userInfo) {
		if (labMemberService.isOwner(userInfo.getLabId(), labMemberId)) {
			throw new BrillilabException("您无法对管理员进行此项操作！");
		}
		if (!userInfo.getId().equals(userInfo.getOwnerId())
				&& power.equals(LabMemberPowerEnum.Power.USER_MANAGE.getValue())) {
			throw new BrillilabException("您不能操作用户管理权限！");
		}

		labMemberPowerService.modifyOne(userInfo.getLabId(), labMemberId, power, isOpen);

		// 推送提醒(修改成功)
		powerModifyMessagePush(labMemberId, userInfo);

		usersLogic.setRefreshUser(labMemberId, "您的权限已被修改，请刷新用户信息！", false);
	}

	/**
	 * 批量修改成员权限
	 *
	 * @param reqList
	 * @param userInfo
	 */
	public void doBatchModifyPower(List<PowerModifyPa> reqList, UserInfoVo userInfo) {
		if (!CollectionUtils.isEmpty(reqList)) {
			labMemberPowerService.batchModifyPower(userInfo, reqList);
			List<Long> labMemberIds = reqList.stream().map(PowerModifyPa::getLabMemberId).distinct()
					.collect(Collectors.toList());
			if (!CollectionUtils.isEmpty(labMemberIds)) {
				List<LabMember> labMembers = labMemberService.selectList(labMemberIds);
				Map<Long, Long> idMap = labMembers.stream()
						.collect(Collectors.toMap(LabMember::getUserId, LabMember::getId));
				AuthByModifySuccessTemplate authByModifySuccessTemplate = new AuthByModifySuccessTemplate(
						userInfo.getLabId(), idMap, userInfo.getName());
				messageProducer.sendMessagePushMutiReceiver(authByModifySuccessTemplate);
//        reqList.forEach(e -> usersLogic.setRefreshUser(e.getLabMemberId(),"您的权限已被修改，请刷新用户信息！"));
			}
		}
	}

	/**
	 * 修改权限和小组
	 *
	 * @param modify
	 * @param userInfo
	 */
	public void modifyPowerAndTeam(PowerAndDutyModifyVo modify, UserInfoVo userInfo) {
		this.doModifyPower(modify.getLabMemberId(), modify.getPowers(), userInfo);
		teamLogic.entryTeam(modify.getLabMemberId(), modify.getTeamId(), userInfo.getLabId());
		LabMember labMember = new LabMember();
		labMember.setId(modify.getLabMemberId());
		labMember.setIsModify(BoolEnum.TRUE.getValue());
		labMemberService.updateById(labMember);
	}

	/**
	 * 获取全部加入实验室记录
	 *
	 * @param userVo
	 * @return
	 */
	public List<HomeMyAuditVo> getAllLastJoinLabList(UserInfoVo userVo) {
		List<HomeMyAuditVo> auditList = new ArrayList<>();
		List<LabMember> lastJoinLabList = labMemberService.getLastJoinLabList(userVo.getLabId());
		// 非PI用户自己返回空
		if (!userVo.getIsOwner()) {
			return auditList;
		}
		HomeMyAuditVo audit = null;
		if (lastJoinLabList != null && lastJoinLabList.size() > 0) {
			for (LabMember member : lastJoinLabList) {
				if (member.getUserId().equals(userVo.getId())) {
					// 过滤当前操作人的数据
					continue;
				}
				// 注册用户加入实验室
				audit = new HomeMyAuditVo();
				audit.setType(MessageTypeEnum.RegisterSuccess.getValue());
				audit.setSendTime(member.getEntryDate());
				audit.setReferId(member.getUserId());
				auditList.add(audit);
			}
		}
		return auditList;
	}

	/**
	 * 根据指定数据封装待审阅记录
	 *
	 * @param auditVoList
	 * @param userVo
	 * @return
	 */
	public List<HomeMyAuditVo> getLastJoinLabList(List<HomeMyAuditVo> auditVoList, UserInfoVo userVo) {
		List<HomeMyAuditVo> auditList = new ArrayList<>();
		if (CollectionUtils.isEmpty(auditVoList) && auditVoList.size() > 0) {
			return auditList;
		}

		List<Long> userIdList = auditVoList.stream().map(p -> p.getReferId()).collect(Collectors.toList());
		List<Users> userList = usersLogic.getUserList(userIdList);
		for (HomeMyAuditVo auditVo : auditVoList) {
			Users users = userList.stream().filter(p -> p.getId().equals(auditVo.getReferId())).findAny().orElse(null);
			if (users == null) {
				continue;
			}
			String content = String.format("<span style='color:#F6AC2D'>%s</span>" + "<span>已加入</span>"
					+ "<span style='color:#F6AC2D'>%s</span>", users.getName(), userVo.getLabName());
			auditVo.setContent(content);
			auditList.add(auditVo);
		}
		return auditList;
	}
}
